package com.yangxk.kadmin.web.common.interceptor;

import com.yangxk.kadmin.common.exception.UnLoginException;
import com.yangxk.kadmin.common.util.ValidUtil;
import com.yangxk.kadmin.web.common.Const;
import com.yangxk.kadmin.web.common.annotation.Permission;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;


/**
 * 权限拦截器
 * @author yangxk
 * @date 2018/10/19 11:29
 */
public class AuthInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if (!(handler instanceof HandlerMethod))
            return true;

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Permission permission = handlerMethod.getMethod().getAnnotation(Permission.class);
        /**
         * 判断是否有权限的规则：
         * 1. 有Permission注解，从注解中获取auth_code
         *      > 有authCode, 则与用户权限比较
         *      > 没有authCode, 则从全局权限中获取当前请求对应的auth_code, 如果没有获取到则为没有权限
         * 2. 没有permission注解，从全局权限中获取当前请求对应的auth_code
         *      > 获取到了，则与用户权限比较
         *      > 没有获取到，则不进行判断
         */
        if (permission == null) {
            String authCode = getUrlAuthCode(request);
            if (ValidUtil.isEmpty(authCode) || hasPermission(request, new String[]{authCode})) {
                return true;
            }
        }

        String[] codes = permission.value();
        if (ValidUtil.isEmpty(codes)) {
            String urlAuthCode = getUrlAuthCode(request);
            if (hasPermission(request, new String[]{urlAuthCode}))
                return true;
        } else {
            if (hasPermission(request, codes))
                return true;
        }

        // 没有权限，抛出异常
        throw new UnLoginException();
    }

    private String getUrlAuthCode(HttpServletRequest request) {
        String servletPath = request.getServletPath();
        Map<String, String> auth = (Map<String, String>)request.getServletContext().getAttribute(Const.CONTEXT_AUTH_KEY);

        String authCode = auth.get(servletPath);

        return authCode;
    }

    private boolean hasPermission(HttpServletRequest request, String[] codes) {
        List<String> userAuth = (List<String>)request.getSession().getAttribute(Const.SESSION_USER_AUTH_KEY);
        for (String code : codes) {
            if (userAuth.contains(code)) // 对于数组，满足一个权限即可
                return true;
        }

        return false;
    }

}
